<?php
namespace Common\Logic;

/**
 * 客栈预定端房间相关逻辑
 * @modify trainyao 2016-05-05 创建
 */
class RoomBookLogic extends \Common\Controller\BaseController {
    
    /**
     * 获取单个或多个房间实时房态
     * 该方法会抛异常
     * @modify trainyao 2016-05-05 创建
     * @param  integer   $hotelId   客栈ID
     * @param  array   $roomId    房型ID
     * @param  string   $startDate 开始时间
     * @param  string   $endDate   结束时间
     * @return array          roomtype_id =>  array(
     *                                 roomtype_id  房型ID
     *                                 rest         房型剩余量
     *                                 room array(
     *                                     id
     *                                     name
     *                                     canBook  0/1
     *                                     date aray('2016-01-01' => 0/1,  '2016-01-02' => 0/1, // 查询的日期内某个日期是否能被预定)
     *                                 )
     *                             )
     */
    public function getInfo($hotelId, array $roomId, $startDate, $endDate) {
        // 根据房间id获取房间信息
        $roomInfoModel = D('RoomInfo');
        $roomInfo = $roomInfoModel->getInfo($roomId);

        // 获取时间段内,相关房间的订单
        $orderRoomModel = D('OrderRoom');
        $orderRooms = $orderRoomModel->getInfoByHotelRoomDate($hotelId, $roomId, $startDate, $endDate);
        $splitOrderRooms = $orderRoomModel->getInfoByHotelRoomDate($hotelId, $roomId, $startDate, $endDate, array(ORDER_BOOKED, ORDER_PAYED, ORDER_CHECKINED, ORDER_OUTDATED), true);
        // 去重
        $orderRooms = getArrayValueAsIndex($orderRooms, 'id');
        foreach ($splitOrderRooms as $key => $splitOrderItem) {
            if (isset($orderRooms[$splitOrderItem['id']])) {
                unset($splitOrderRooms[$key]);
            }
        }
        unset($splitOrderItem);
        $orderRooms = array_merge($orderRooms, $splitOrderRooms);

        // 从redis读取数据,将有效已过期订单变为已预订
        if (!empty($orderRooms)) {
            $outDateOrderRoomIds = array();
            foreach ($orderRooms as $orderRoomItem) {
                if ($orderRoomItem['status'] == ORDER_OUTDATED) {
                    array_push($outDateOrderRoomIds, $orderRoomItem['id']);
                }
            }
            unset($orderRoomItem);
            if (!empty($outDateOrderRoomIds)) {
                $orderRooms = getArrayValueAsIndex($orderRooms, 'id');
                $redisOrderRecordInfo = $orderRoomModel->getInfoInRedisByHotelRoomOrderRoom($hotelId, null, $outDateOrderRoomIds);
                if ($redisOrderRecordInfo === false) {
                    // redis查询失败
                    throw new \Exception('500,512', 512);
                }
                foreach ($redisOrderRecordInfo as $redisOrderRecordItem) {
                    $orderRooms[$redisOrderRecordItem['orderroom_id']]['status'] = ORDER_BOOKED;
                }
                unset($redisOrderRecordItem);
            }
        }

        // 组装数据返回
        if (!empty($orderRooms)) {
            $orderRooms = getArrayValueAsIndex($orderRooms, 'roominfo_id', 'multi');
        }
        if (count($roomId) == 1) {
            $roomInfo = array($roomInfo);
        }
        $roomInfo = getArrayValueAsIndex($roomInfo, 'roomtype_id', 'multi');
        $roomTypeIds = array_keys($roomInfo);
        // 维修房数据
        $roomServiceModel = D('RoomService');
        $roomServiceList = $roomServiceModel->getServiceList($roomTypeIds, null, null, NOT_DELETE);
        $roomServiceList = getArrayValueAsIndex($roomServiceList, 'roominfo_id');
        $startTimestamp = strtotime($startDate);
        $endTimestamp = strtotime($endDate) - 86400;

        $nights = getNight($startDate, $endDate);
        foreach ($roomInfo as $roomTypeId => &$roomInfoItems) {
            $roomInfoItems = array(
                'roomtype_id' => $roomTypeId,
                'rest' => count($roomInfoItems),
                'room' => $roomInfoItems,
            );
            foreach ($roomInfoItems['room'] as $key => &$roomItem) {
                // 过滤维修房
                if (isset($roomServiceList[$roomItem['id']])) {
                    // 到结束日期
                    $roomServiceStartTime = $roomServiceList[$roomItem['id']]['startdate'];
                    $roomServiceEndTime = $roomServiceList[$roomItem['id']]['enddate'];
                    if (($roomServiceStartTime <= $startTimestamp && $startTimestamp <= $roomServiceEndTime) || ($roomServiceStartTime <= $endTimestamp && $endTimestamp <= $roomServiceEndTime)) {
                        $roomInfoItems['rest']--;
                        unset($roomInfoItems['room'][$key]);
                        continue;
                    }
                }
                // 为每个房型初始化日期是否能预定
                $roomItem['date'] = array();
                $dateCounter = $startDate;
                for ($i=0; $i < $nights; $i++) {
                    $roomItem['date'][$dateCounter] = ENABLE;
                    $dateCounter = date('Y-m-d', strtotime($dateCounter . ' +1 days'));
                }
                unset($i);

                $roomItemCanCheckin = true;
                // 查看该房间id,时间段内是否订单
                if (isset($orderRooms[$roomItem['id']])) {
                    foreach ($orderRooms[$roomItem['id']] as $orderRoomItem) {
                        // 将房间被订单占用的日期设为不能预定
                        if ($orderRoomItem['realnight'] > 0 && $orderRoomItem['status'] != ORDER_OUTDATED) {
                            $dateCounter = substr($orderRoomItem['startdate'], 0, 10);
                            for ($i=0; $i < $orderRoomItem['realnight']; $i++) {
                                // (只把需要查询的日期设为不能预定,以防多返回Ymd=>DISABLE)
                                if (isset($roomItem['date'][$dateCounter])) {
                                    $roomItem['date'][$dateCounter] = DISABLE;
                                }
                                $dateCounter = date('Y-m-d', strtotime($dateCounter . ' +1 days'));
                            }
                            unset($i);
                            $roomItemCanCheckin = false;
                        }
                        if ($orderRoomItem['hour'] > 0 && $orderRoomItem['status'] != ORDER_OUTDATED && $orderRoomItem['status'] != ORDER_CANCELED && $orderRoomItem['status'] != ORDER_CHECKOUTED) {
                            $roomItemCanCheckin = false;
                        }
                    }
                    unset($orderRoomItem);
                }

                if (!$roomItemCanCheckin) {
                    $roomInfoItems['rest']--;
                    $roomItem['canBook'] = DISABLE;
                } else {
                    $roomItem['canBook'] = ENABLE;
                    // 脏房
                    if ($roomItem['isdirty'] == ROOM_DIRTY) {
                        $roomInfoItems['rest']--;
                    }
                }
            }
            unset($roomItem);
            $roomInfoItems['room'] = array_values($roomInfoItems['room']);
        }
        unset($roomInfoItems);

        return $roomInfo;
    }
}
